package com.lyl.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.lyl.model.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author lylbell
 * @date 2021-06-24 16:05
 */
@RestController
@Api(tags = "文件上传")
public class FileController {


    @Autowired
    private OSS ossClient;   //alicloud-oss中导入的，爆红没有关系

    //阿里云的oss对象存储上面的bucket名字
    @Value("${oss.bucket.name:lyl-coin-exchange-images}")
    private String bucketName ;

    @Value("${spring.cloud.alicloud.oss.endpoint}")//配置文件上面的
    private String endPoint ;

    @Value("${oss.callbackUrl:47.107.50.129:9000}")
    private String callbackUrl;

    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;


    @PostMapping("/image/AliYunImgUpload")
    @ApiOperation(value="上传文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file",value = "上传的文件")
    })
    public Result<String> fileUpload(@RequestParam("file") MultipartFile file) throws IOException {
        String filename = DateUtil.today().replaceAll("-","/") + "/" + file.getOriginalFilename();
        ossClient.putObject(bucketName,filename,file.getInputStream());
        //上传成功后的路径为：https://bucketName.endPoint/filename
        return Result.ok("https://" + bucketName + "." +endPoint + "/" + filename);
    }

    @GetMapping("/image/pre/upload")
    @ApiOperation("web直传oss,获取后端返回的policy")
    public Result<Map<String, String>> preUpload() {
        String dir = DateUtil.today().replaceAll("-","/") + "/";
        //前端获取后端返回的policy和sign
        Map<String, String> uploadPolicy = getUploadPolicy(30L, 3 * 1024 * 1024L, dir);
        return Result.ok(uploadPolicy);
    }

    //参考代码：https://help.aliyun.com/document_detail/91868.html?spm=a2c4g.11186623.2.15.16076e28Cw94Ga#concept-ahk-rfz-2fb
    private Map<String,String> getUploadPolicy(Long expireTime,Long maxfileSize,String dir) {
        try{
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            // PostObject请求最大可支持的文件大小为5 GB，即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxfileSize);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", "https://" + bucketName + "." + endPoint); //设置上传的host：https://buckName.endpoint
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            // respMap.put("expire", formatISO8601Date(expiration));

            JSONObject jasonCallback = new JSONObject();
            jasonCallback.put("callbackUrl", callbackUrl);//当前端上传文件到oss服务器成功后，oss服务器会想回调callbackUrl，发一个post请求来告诉后端服务器用户上传文件的情况。
            jasonCallback.put("callbackBody",
                    "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
            jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
            String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
            respMap.put("callback", base64CallbackBody);
            return respMap;
        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        }
        return null;
    }
}
